home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UMacAppUniversal.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  19.8 KB  |  690 lines  |  [TEXT/MPS ]

  1. //UMacAppUniversal.cp
  2. //Copyright © 1984-1991 Apple Computer, Inc.  All rights reserved.
  3.  
  4. #include "UMacAppUniversal.h"
  5.  
  6. #ifndef __GEOMETRY__
  7. #include <Geometry.h>
  8. #endif
  9.  
  10. #ifndef __TRAPS__
  11. #include <Traps.h>
  12. #endif
  13.  
  14. #ifndef __SYSEQU__
  15. #include <SysEqu.h>
  16. #endif
  17.  
  18. #ifndef __DEVICES__
  19. #include <Devices.h>
  20. #endif
  21.  
  22. #ifndef __ULOMEM__
  23. #include <ULoMem.h>
  24. #endif
  25.  
  26. #ifndef __MEMORY__
  27. #include <Memory.h>
  28. #endif
  29.  
  30. #ifndef __TOOLUTILS__
  31. #include <ToolUtils.h>
  32. #endif
  33.  
  34. #ifndef __RESOURCES__
  35. #include <Resources.h>
  36. #endif
  37.  
  38. #ifndef __FONTS__
  39. #include <Fonts.h>
  40. #endif
  41.  
  42. #ifndef __SCRAP__
  43. #include <Scrap.h>
  44. #endif
  45.  
  46. #ifndef __ERRORS__
  47. #include <Errors.h>
  48. #endif
  49.  
  50. #ifndef __DIALOGS__
  51. #include <Dialogs.h>
  52. #endif
  53.  
  54. #ifndef __PACKAGES__
  55. #include <Packages.h>
  56. #endif
  57.  
  58. #ifndef __SCRIPT__
  59. #include <Script.h>
  60. #endif
  61.  
  62. #ifndef __OSEVENTS__
  63. #include <OSEvents.h>
  64. #endif
  65.  
  66. #ifndef __SANE__
  67. #include <SANE.h>
  68. #endif
  69.  
  70. #ifndef __GESTALTEQU__
  71. #include <GestaltEqu.h>
  72. #endif
  73.  
  74. #ifndef __EDITIONS__
  75. #include <Editions.h>
  76. #endif
  77.  
  78. #ifndef __QUICKDRAW__
  79. #include <QuickDraw.h>
  80. #endif
  81.  
  82. #ifndef __MENUS__
  83. #include <Menus.h>
  84. #endif
  85.  
  86. #ifndef    __UDebug__
  87. #include "UDebug.h"
  88. #endif
  89.  
  90. #ifndef    __UERRORMGR__
  91. #include "UErrorMgr.h"
  92. #endif
  93.  
  94. #ifndef    __UMEMORY__
  95. #include "UMemory.h"
  96. #endif
  97.  
  98. #ifndef    __UMACAPPUTILITIES__
  99. #include "UMacAppUtilities.h"
  100. #endif
  101.  
  102. //--------------------------------------------------------------------------------------------------
  103. // Nothing in this module can be allowed to fail!
  104. #pragma    $MC68020-
  105.  
  106. //--------------------------------------------------------------------------------------------------
  107. #pragma segment MAUtilitiesRes
  108.  
  109. pascal void BlockSet(Ptr destPtr,
  110.                      long byteCount,
  111.                      SignedByte setVal)
  112. // Much thanks for this improved version to Scott D. Schmitz 
  113.  
  114. {
  115.     Ptr endPtr = NULL;
  116.     long longSetVal = 0;
  117.     LongIntPtr longEndPtr = NULL;
  118.     LongIntPtr longSetValPtr;
  119.  
  120.     destPtr = (Ptr)StripLong(destPtr);
  121.     endPtr = (Ptr)(destPtr + byteCount);
  122.     longEndPtr = (LongIntPtr)(destPtr + (byteCount & 0xFFFFFFFC));//Trunc to nearest 4 bytes
  123.  
  124.     //We do longword assignments when we have a chance
  125.     if (byteCount >= 4)
  126.     {
  127.         if ((((long)destPtr) & 1) == 1)            //Starting on an odd byte boundry
  128.             *destPtr++ = setVal;
  129.  
  130.         longSetVal = (setVal << 12) + (setVal << 8) + (setVal << 4) + setVal;// Lets get a 4 byte 'punch'.
  131.  
  132.         //Assign in 4 byte chunks what we can
  133.         for (longSetValPtr = (LongIntPtr)destPtr; longSetValPtr < longEndPtr;)
  134.             *longSetValPtr++ = longSetVal;
  135.         destPtr = (Ptr)longSetValPtr;
  136.     }
  137.  
  138.     //Now finish assigning odd bytes
  139.     while (destPtr < endPtr)
  140.         *destPtr++ = setVal;
  141. }
  142.  
  143. //--------------------------------------------------------------------------------------------------
  144. #pragma segment MAUtilitiesRes
  145. // This must always be in a resident segment as aRect may be within a handle
  146.  
  147. pascal void CenterRectOnScreen(Rect& aRect,
  148.                                Boolean horizontally,
  149.                                Boolean vertically,
  150.                                Boolean forDialog)
  151.  
  152. {
  153.     Point screenSize(qd.screenBits.bounds.Length(vSel) - GetMBarHeight(), qd.screenBits.bounds.Length(hSel));
  154.     Point rectSize(aRect.Length(vSel), aRect.Length(hSel));
  155.     short newSize = 0;
  156.  
  157.     // Calculate screen size minus menu bar 
  158.     if (horizontally)
  159.         aRect.left = (screenSize.h - rectSize.h) / 2;
  160.     if (vertically)
  161.         if (forDialog)
  162.         {
  163.             newSize = (screenSize.v - rectSize.v) / 5;
  164.             aRect.top = (short)(Max(newSize, 10) + GetMBarHeight());
  165.         }
  166.         else
  167.             aRect.top = (screenSize.v - rectSize.v) / 2;
  168.  
  169.     aRect.right = aRect.left + rectSize.h;
  170.     aRect.bottom = aRect.top + rectSize.v;
  171. }
  172.  
  173. //--------------------------------------------------------------------------------------------------
  174. #pragma segment MAUtilitiesRes
  175.  
  176. pascal void ConcatNumber(const Str255& aString,
  177.                            long aNumber,
  178.                            Str255& theResult)
  179.  
  180. {
  181.     NumToString(aNumber, theResult);
  182.     theResult = aString + theResult;
  183. }
  184.  
  185. //--------------------------------------------------------------------------------------------------
  186. #pragma segment MAUtilitiesRes
  187.  
  188. pascal TrapType GetTrapType(short theTrap)
  189.  
  190. {
  191.     // OS traps start with A0, Tool with A8 or AA. 
  192.     if ((theTrap & 0x0800) == 0)                // per D.A.
  193.         return OSTrap;
  194.     else
  195.         return ToolTrap;
  196. }
  197.  
  198. //--------------------------------------------------------------------------------------------------
  199. #pragma segment MAMiniInit
  200.  
  201. pascal void DoRealInitToolBox(void)
  202.  
  203. {
  204.     InitGraf(&qd.thePort);
  205.     InitFonts();
  206.     InitWindows();                                // creates non-relocatable for the WM port 
  207.  
  208.     // _DON'T_ flush disk-inserted or os events or you'll be sorry! 
  209.     FlushEvents(everyEvent - diskMask - osMask, 0);
  210.  
  211.     InitMenus();
  212.     TEInit();
  213.     InitDialogs(NULL);
  214.     CursHandle aCursHandle = GetCursor(watchCursor);        /* Watch should be in system file, but just
  215.                                                   in case… */
  216.  
  217.     InitCursor();                                /* !!! This forces an arrow cursor. Is there
  218.                                                   a way to reset the show/hide level and
  219.                                                   init all the cursor goo without having
  220.                                                   this visual glitch? ( the Finder™ sets the
  221.                                                   cursor to a watch when launching. It would
  222.                                                   be nice to stay that way until the app is
  223.                                                   ready for events. */
  224.     if (aCursHandle)
  225.         SetCursor(**aCursHandle);                // Change cursor to watch 
  226.  
  227.     /* -1 == 0xFFFFFFFF, the largest 32 bit address.  Our routine StripLong uses a pre-stripped
  228.       address gStrippedAddress to avoid the yucky MPW glue.
  229.       (NOTE: need gStrippedAddress in DefineConfiguration.) */
  230.     gStrippedAddress = StripAddress((Ptr) - 1);
  231.  
  232.     // Find out just what kind of environment we're dealing with here 
  233.     DefineConfiguration(gConfiguration);
  234.  
  235.     // Init all the primary colors 
  236.     SetRGBColor(gRGBBlack, 0, 0, 0);
  237.     SetRGBColor(gRGBWhite, 0xFFFF, 0xFFFF, 0xFFFF);
  238.     SetRGBColor(gRGBRed, 0xFFFF, 0, 0);
  239.     SetRGBColor(gRGBGreen, 0, 0xFFFF, 0);
  240.     SetRGBColor(gRGBBlue, 0, 0, 0xFFFF);
  241.  
  242. #if qDebug || qInspector
  243.     gFieldToStrRtn = (ProcPtr) & StdFieldToString;
  244.     gFieldToCountRtn = (ProcPtr) & StdFieldToCount;
  245. #endif
  246.  
  247.     gBoolString[0][0] = (char)5;                // = "\pFALSE";
  248.     gBoolString[0][1] = 'F';
  249.     gBoolString[0][2] = 'A';
  250.     gBoolString[0][3] = 'L';
  251.     gBoolString[0][4] = 'S';
  252.     gBoolString[0][5] = 'E';
  253.     gBoolString[1][0] = (char)4;                // = "\pTRUE";
  254.     gBoolString[1][1] = 'T';
  255.     gBoolString[1][2] = 'R';
  256.     gBoolString[1][3] = 'U';
  257.     gBoolString[1][4] = 'E';
  258.  
  259.     // The refnum where the application's resources should be found 
  260.     gApplicationRefNum = CurResFile();
  261.  
  262.     gToolBoxInitialized = TRUE;
  263. }
  264.  
  265. //--------------------------------------------------------------------------------------------------
  266. #pragma segment Main
  267. // This procedure is intended to be in "Main" which is already loaded
  268.  
  269. extern pascal void _DataInit(void);                // Routine in the A5 globals initializer 
  270.  
  271. pascal void FailedInitToolBox(void)
  272.  
  273. {
  274.     if (qDebug)
  275.         DebugStr("Not enough room to init ToolBox Managers");
  276.     ExitToShell();                                /*??? any good way to signal this to the user
  277.                                                   ???*/
  278. }
  279.  
  280. pascal void InitToolBox(void)
  281.  
  282. {
  283.     const short kBreathingRoom = 1024;            // Amount of heap space needed for init 
  284.     Size totalSize = 0;
  285.     Size contigSize = 0;
  286.     Handle h = NULL;
  287.  
  288.     /* the heap and stack don't overlap. So there's enough room to init the managers.
  289.       Make sure that the MAMiniInit Segment can be loaded and that there's still a little
  290.       Room after that. */
  291.  
  292.     UnloadSeg(&_DataInit);                        // Toss some ballast 
  293.  
  294.     /* "MAMain" this is MacApp's own code that must be resident… even before/during the UMemory startup.
  295.     GetNamedResource will call RsrvMem which locates the handle as low in memory as possible.
  296.     We will then lock it there… just like "Main".  In order for this to work correctly the build system
  297.     will have to have set the locked bit on the MAMain resource. */
  298.     h = GetNamedResource('CODE', "MAMain");
  299.     if (h)
  300.         HNoPurge(h);
  301.     else
  302.         FailedInitToolBox();
  303.  
  304.     h = GetNamedResource('CODE', "MAMiniInit");
  305.     if (h)
  306.         HNoPurge(h);    /* don't let it get squished out of the heap when the grow zone might get called
  307.                     below.  However, since it is not locked it will float up to the top of the heap
  308.                     when it is entered at DoRealInitToolBox. */
  309.                     
  310.     else
  311.         FailedInitToolBox();
  312.  
  313.     /* Attempt to ensure that there is going to be kBreathingRoom bytes available in the heap so that
  314.       when the actual toolbox managers are initialized there is a significantly reduced chance that
  315.       they will express their displeasure with us through SysErr -25 or -2.  If the space is not
  316.       currently available in the zone as shown by PurgeSpace then attempting to allocate it will let
  317.       growzoneproc operate and grow the zone a little, as necessary.    If, after that, we haven't been
  318.       able to get the breathing room we desire then just give up and fade silently away. (Like the old
  319.       soldier, not the old executive). */
  320.  
  321.     PurgeSpace(totalSize, contigSize);
  322.  
  323.     if (totalSize >= kBreathingRoom)
  324.         DoRealInitToolBox();
  325.     else
  326.     {
  327.         h = NewHandle(kBreathingRoom);
  328.         if (h != NULL)                            // get the grow space 
  329.         {
  330.             DisposHandle(h);
  331.             DoRealInitToolBox();
  332.         }
  333.         else
  334.             FailedInitToolBox();                // Give up 
  335.     }
  336. }
  337.  
  338. //--------------------------------------------------------------------------------------------------
  339. #pragma segment MAMiniInit
  340.  
  341. pascal Boolean ValidateConfiguration(const ConfigRecord& configuration)
  342.  
  343. {
  344.     Boolean isSupported = TRUE;
  345.  
  346.     /* Run the gauntlet of support tests using the conditionally set constants.
  347.       If any single test fails then the app is considered unsupported on this machine.  */
  348.  
  349.     // Required minimums 
  350.     isSupported = isSupported && configuration.hasROM128K;
  351.     isSupported = isSupported && configuration.hasScriptManager;
  352.     isSupported = isSupported && configuration.hasHierarchicalMenus;
  353.     isSupported = isSupported && configuration.hasStyleTextEdit;
  354.     isSupported = isSupported && configuration.hasWaitNextEvent;
  355.  
  356.     // Optionally required 
  357.     if (qNeedsColorQD)
  358.         isSupported = isSupported && configuration.hasColorQD;
  359.  
  360.     if (qNeedsMC68020)
  361.         isSupported = isSupported && ((configuration.processor != gestalt68000) && (configuration.processor != gestalt68010));
  362.  
  363.     if (qNeedsMC68030)
  364.         isSupported = isSupported && ((configuration.processor != gestalt68000) && (configuration.processor != gestalt68010) && (configuration.processor != gestalt68020));
  365.  
  366.     if (qNeedsFPU)
  367.         isSupported = isSupported && configuration.hasFPU;
  368.  
  369.     // System 7.0 Support 
  370.  
  371.     if (qNeedsAppleEventMgr)
  372.         isSupported = isSupported && configuration.hasAppleEventMgr;
  373.  
  374.     if (qNeedsEditionMgr)
  375.         isSupported = isSupported && configuration.hasEditionMgr;
  376.  
  377.     if (qNeedsHelpMgr)
  378.         isSupported = isSupported && configuration.hasHelpMgr;
  379.  
  380.     if (qNeedsAliasMgr)
  381.         isSupported = isSupported && configuration.hasAliasMgr;
  382.  
  383.     if (qNeedsFolderMgr)
  384.         isSupported = isSupported && configuration.hasFolderMgr;
  385.  
  386.     if (qNeedsProcessMgr)
  387.         isSupported = isSupported && configuration.hasProcessMgr;
  388.  
  389.     return isSupported;
  390. }
  391.  
  392. //--------------------------------------------------------------------------------------------------
  393. #pragma segment MAMiniInit
  394.  
  395. pascal short GetSysMap(void) = {                /* kMoveWAbsolute */
  396.                                 0x3EB8,            /* SysMap */ 0xA58};/* retrieve global; reference number of
  397.                                                   system map */
  398. // MOVE.W SysMap,(SP) 
  399.  
  400. short GetSysVRefNum(void)
  401. // return the working directory refNum corresponding to the currently open System File 
  402.  
  403. {
  404.     FCBPBRec aFCBPBRec;
  405.     HParamBlockRec aHParamBlockRec;
  406.     WDPBRec aWDPBRec;
  407.  
  408.     // get file info for open system file rsrc fork 
  409.     BlockSet((Ptr) & aFCBPBRec, sizeof(FCBPBRec), 0x00);
  410.     aFCBPBRec.ioRefNum = GetSysMap();
  411.     if (PBGetFCBInfoSync(&aFCBPBRec) != noErr)
  412.         return 0;
  413.     else
  414.     {
  415.         // get volume info for open system file rsrc fork 
  416.         BlockSet((Ptr) & aHParamBlockRec, sizeof(HParamBlockRec), 0x00);
  417.         aHParamBlockRec.volumeParam.ioVRefNum = aFCBPBRec.ioFCBVRefNum;
  418.         if (PBHGetVInfoSync(&aHParamBlockRec) != noErr)
  419.             return 0;
  420.         else
  421.         {
  422.             // open a working directory for system file and return a reference to it 
  423.             BlockSet((Ptr) & aWDPBRec, sizeof(WDPBRec), 0x00);
  424.             aWDPBRec.ioVRefNum = aHParamBlockRec.volumeParam.ioVRefNum;
  425.             aWDPBRec.ioWDDirID = aHParamBlockRec.volumeParam.ioVFndrInfo[0];
  426.             aWDPBRec.ioWDProcID = 'ERIK';        //0x4552494B;                    //'ERIK'
  427.             if (PBOpenWDSync(&aWDPBRec) != noErr)
  428.                 return 0;
  429.             else
  430.                 return aWDPBRec.ioVRefNum;
  431.         }
  432.     }
  433. }
  434.  
  435. //--------------------------------------------------------------------------------------------------
  436. #pragma segment MAMiniInit
  437.  
  438. Boolean HasGestaltAttr(OSType itsAttr,
  439.                        short itsBit)
  440.  
  441. {
  442.     long response;
  443.  
  444.     return (Gestalt(itsAttr, response) == noErr) && (((response >> itsBit) & 1) != 0);
  445. }
  446.  
  447.  
  448. pascal void DefineConfiguration(ConfigRecord& configuration)
  449.  
  450. {
  451.     const short mDesktopBus = 0x0400;
  452.  
  453.     OSErr err;
  454.     long response;
  455.  
  456.     err = Gestalt(gestaltVersion, response);
  457.     configuration.environsVersion = (short)response;
  458.  
  459.     err = Gestalt(gestaltMachineType, response);
  460.     configuration.machineType = (short)response;
  461.  
  462.     configuration.hasROM128K = configuration.machineType >= gestaltMac512KE;
  463.     if (configuration.hasROM128K)
  464.         configuration.hasHFS = TRUE;
  465.     else
  466.         configuration.hasHFS = GetFSFCBLen() > 0;
  467.  
  468.     err = Gestalt(gestaltSystemVersion, response);
  469.     configuration.systemVersion = (short)response;
  470.  
  471.     err = Gestalt(gestaltProcessorType, response);
  472.     configuration.processor = (short)response;
  473.  
  474.     err = Gestalt(gestaltFPUType, response);
  475.     configuration.hasFPU = response != gestaltNoFPU;
  476.  
  477.     err = Gestalt(gestaltQuickdrawVersion, response);
  478.     configuration.hasColorQD = response != gestaltOriginalQD;
  479.  
  480.     err = Gestalt(gestaltQuickdrawVersion, response);
  481.     configuration.has32BitQD = configuration.hasColorQD && (response != gestalt8BitQD);
  482.  
  483.     err = Gestalt(gestaltKeyboardType, response);
  484.     configuration.keyboardType = (short)response;
  485.  
  486.     err = Gestalt(gestaltMachineType, response);
  487.     configuration.atDrvrVersNum = (short)response;
  488.  
  489.     configuration.hasSCSI = HasGestaltAttr(gestaltHardwareAttr, gestaltHasSCSI);
  490.  
  491.     err = Gestalt(gestaltAUXVersion, response);
  492.     configuration.hasAUX = response != 0;
  493.  
  494.     err = Gestalt(gestaltScriptMgrVersion, response);
  495.     configuration.hasScriptManager = configuration.hasROM128K && (response != 0);
  496.  
  497.     configuration.hasTempMem = HasGestaltAttr(gestaltOSAttr, gestaltTempMemSupport);
  498.  
  499.     //!!! still need to set Atversion 
  500.  
  501.     configuration.sysVRefNum = GetSysVRefNum();
  502.  
  503.     err = Gestalt(gestaltTextEditVersion, response);
  504.     configuration.teVersion = response;
  505.  
  506.     configuration.hasDesktopBus = (GetHwCfgFlags() & mDesktopBus) > 0;
  507.  
  508.     configuration.hasHierarchicalMenus = configuration.hasROM128K && TrapExists(_PopUpMenuSelect);
  509.  
  510.     configuration.hasStyleTextEdit = configuration.systemVersion >= 0x600;
  511.     configuration.hasSoundManager = configuration.hasROM128K && TrapExists(_SndDoCommand);
  512.     configuration.hasWaitNextEvent = configuration.hasROM128K && TrapExists(_WaitNextEvent);
  513.  
  514.     // System 7.0 support 
  515.     configuration.hasAppleEventMgr = HasGestaltAttr(gestaltAppleEventsAttr, gestaltAppleEventsPresent);
  516.     configuration.hasEditionMgr = HasGestaltAttr(gestaltEditionMgrAttr, gestaltEditionMgrPresent);
  517.     configuration.hasHelpMgr = HasGestaltAttr(gestaltHelpMgrAttr, gestaltHelpMgrPresent);
  518.     configuration.hasAliasMgr = HasGestaltAttr(gestaltAliasMgrAttr, gestaltAliasMgrPresent);
  519.     configuration.hasFolderMgr = HasGestaltAttr(gestaltFindFolderAttr, gestaltFindFolderPresent);
  520.     configuration.hasPopupCDEF = HasGestaltAttr(gestaltPopupAttr, gestaltPopupPresent);
  521.  
  522.     if (configuration.systemVersion >= 0x700)    // why isn't there a Gestalt selector ??? 
  523.         configuration.hasProcessMgr = TRUE;
  524.     else
  525.         configuration.hasProcessMgr = FALSE;
  526. }
  527.  
  528. //--------------------------------------------------------------------------------------------------
  529. #pragma segment Main
  530. pascal void HdlInitFailed(short error,
  531.                           long message,
  532.                           void* )
  533.  
  534. {
  535.     //!!! would be nice to unloadallsegments here if (the memory unit is inited 
  536.     if (error != noErr)                            /* check to see if an alert has already been
  537.                                                   displayed */
  538.     {
  539.         if (message == 0)
  540.             message = msgInitFailed;            // if no message specified, use our own 
  541.  
  542. #if qDebug
  543.         // UnloadSeg(&PLFlush);    ¿¿¿ what's the equivalent for C++ ???
  544. #endif
  545.  
  546.         ErrorAlert(error, message);
  547.  
  548.         ExitToShell();
  549.     }
  550. }
  551.  
  552. //--------------------------------------------------------------------------------------------------
  553. #pragma segment Main
  554. // Essential one-time initialization 
  555.  
  556. void ClearTheFPU(void) = { 0x42A7, 0x42A7, 0xF21F, 0x9800 };
  557. //    INLINE 0x42A7,                                        // CLR.L -(A7) 
  558. //           0x42A7,                                        // CLR.L -(A7) 
  559. //           0xF21F, 0x9800;                                // FMOVEM (A7)+, FPCR/FPSR 
  560.  
  561. pascal void InitUMacApp(short callsToMoreMasters)
  562. // Must be in the Main segment since all other segments get unloaded from here.
  563.  
  564. {
  565.     short initSeg;
  566.     THz applZone;
  567.     short oldMoreMast;
  568.  
  569.     if (!gToolBoxInitialized)
  570.         InitToolBox();
  571.  
  572.     if (ValidateConfiguration(gConfiguration))    /* Make sure we can run. The programmer
  573.                                                   really should have ensured this in their
  574.                                                   "M" file but this is a backup check just
  575.                                                   in case. After all 68000's don't really
  576.                                                   like to RTD.*/
  577.     {
  578.         /* the main procedure is always compiled with universal code so, the FPU must be reset before it
  579.           is used.  We could get spurious crashes or worse.
  580.           Remember: 2+2=4… every time!
  581.         */
  582.         if (qNeedsFPU || gConfiguration.hasFPU)
  583.             ClearTheFPU();
  584.  
  585.         // Init the basics used by the ErrorMgr 
  586.         gMacAppAlertFilter = (ProcPtr) & MacAppAlertFilter;
  587.         gInFilter = FALSE;
  588.         gInhibitNestedHandling = FALSE;            // Allow nested handling 
  589.  
  590.         // Install the permanent Outermost failure handler 
  591.         long junk;
  592.         CatchFailures(pFi, &HdlInitFailed, &junk);
  593.  
  594.         // Install MacApp's Memory management system 
  595.         InitUMemory();
  596.  
  597.         UnloadAllSegments();
  598.  
  599.         // Here is a trick suggested by Jerome C.--it allocates one large block of master pointers 
  600.         applZone = ApplicZone();
  601.         oldMoreMast = applZone->moreMast;
  602.         applZone->moreMast = oldMoreMast * callsToMoreMasters;
  603.         MoreMasters();
  604.         applZone->moreMast = oldMoreMast;
  605.  
  606.         LoadResidentSegments();
  607.  
  608.         // Force the init segment to be memory resident, so we can call UnloadAllSegs during init 
  609.         initSeg = GetSegNumber((ProcPtr) & DoInitUMacApp);
  610.         SetResidentSegment(initSeg, TRUE);
  611.  
  612.         DoInitUMacApp();                        // do rest of initialization 
  613.  
  614.         SetResidentSegment(initSeg, FALSE);        // make it non-resident 
  615.         UnloadAllSegments();
  616.     }
  617.     else
  618.     {
  619.         StdAlert(phUnsupportedConfiguration);
  620.         ExitToShell();                            // leave the application pronto! 
  621.     }
  622. }
  623.  
  624. //--------------------------------------------------------------------------------------------------
  625. #pragma segment Main
  626. // Must be in main segment as it is called in early initialization && in MacAppAlert
  627.  
  628. pascal void PullApplicationToFront(void)
  629.  
  630. {
  631.     EventRecord theEvent;
  632.  
  633.     /* The "Programmer's guide to MultiFinder™ says make an event call several times.
  634.       I guess 3 calls counts as several.    Also, it says call GetNextEvent but we don't
  635.       want to lose events on the floor so we use EventAvail since it seems to work OK */
  636.     for (short i = 1; i <= 3; ++i)
  637.         EventAvail(everyEvent, theEvent);
  638. }
  639.  
  640. //--------------------------------------------------------------------------------------------------
  641. // Must be in Main segment, and generic code, because InitToolBox calls this.
  642. #pragma segment Main
  643.  
  644. pascal void SetRGBColor(RGBColor& RGB,
  645.                         short aRed,
  646.                         short aGreen,
  647.                         short aBlue)
  648.  
  649. {
  650.     RGB.red = aRed;
  651.     RGB.green = aGreen;
  652.     RGB.blue = aBlue;
  653. }
  654.  
  655. //--------------------------------------------------------------------------------------------------
  656. #pragma segment MAUtilitiesRes
  657.  
  658. short NumToolboxTraps(void)
  659. /* InitGraf is always implemented (trap 0xA86E). If the trap table is big enough, trap 0xAA6E
  660.   will always point to either Unimplemented or some other trap, but will never be the same
  661.   as InitGraf. Thus, you can check the size of the trap table by asking if the address of
  662.   trap 0xA86E is the same as 0xAA6E. */
  663.  
  664. {
  665.     if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  666.         return 0x200;
  667.     else
  668.         return 0x400;
  669. }
  670.  
  671. //--------------------------------------------------------------------------------------------------
  672. #pragma segment MAUtilitiesRes
  673.  
  674. pascal Boolean TrapExists(short theTrap)
  675.  
  676. {
  677.     TrapType theTrapType = GetTrapType(theTrap);
  678.     short localTrap = theTrap;                    // since theTrap is a const
  679.     if (theTrapType == ToolTrap)
  680.     {
  681.         localTrap = (localTrap & 0x07FF);
  682.         if (localTrap >= NumToolboxTraps())
  683.             localTrap = _Unimplemented;
  684.     }
  685.  
  686.     return NGetTrapAddress(_Unimplemented, ToolTrap) != NGetTrapAddress(localTrap, theTrapType);
  687. }
  688.  
  689.  
  690.